package com.ywu.standard.gateway.handler.user;

import com.ywu.application.spi.dto.YwuAppDto;
import com.ywu.application.spi.spi.YwuApplicationSpi;
import com.ywu.boot.config.BootConfigAppConfig;
import com.ywu.boot.context.YwuContext;
import com.ywu.boot.context.YwuContextHolder;
import com.ywu.common.constant.CommonConstant;
import com.ywu.common.gson.GsonUtils;
import com.ywu.common.result.CommonResult;
import com.ywu.common.utils.AesUtils;
import com.ywu.standard.gateway.handler.user.impl.UserMssaHandlerInterface;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * @ClassName UserAppInfoMssaHandler
 * @Description TODO
 * @Author GroundDemo
 * @Date 2024/9/28 9:48
 * @Version 1.0
 **/
@Component
@Slf4j
@Order(2)
public class UserAppInfoMssaHandler implements UserMssaHandlerInterface {
    private static final String OPEN_SERVICE_CONTEXT = "X-Pix-Ywu-Open-Service";

    @Autowired
    private BootConfigAppConfig bootConfigAppConfig;

    @Autowired
    private YwuApplicationSpi ywuApplicationSpi;

    @Override
    public Object handle(ServerWebExchange exchange) {
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        // 根据上下文中的appToken和appId，校验与服务中的值是否一致
        YwuAppDto ywuAppDto = new YwuAppDto();
        ywuAppDto.setAppId(currentContext.getYwuContextApp().getAppId());
        ywuAppDto.setAppToken(currentContext.getYwuContextApp().getAppToken());
        CompletableFuture<CommonResult<Object>> commonResultCompletableFuture =
                CompletableFuture.supplyAsync(() -> ywuApplicationSpi.checkAppToken(ywuAppDto));
        CommonResult<Object> objectCommonResult;
        try {
            objectCommonResult = commonResultCompletableFuture.get();
        } catch (InterruptedException | ExecutionException e) {
            log.error("UserAppInfoMssaHandler checkAppTokenSpi error {}", e.getMessage());
            return CommonResult.error().setCode(CommonConstant.AUTH_TOKEN_CHECK_SPI_ERROR)
                    .setErrorCode(CommonConstant.AUTH_TOKEN_CHECK_SPI_MESSAGE)
                    .setMessage("SPI调用失败!");
        }
        // 判断校验结果
        if (!objectCommonResult.getCode().equals("200")) {
            return CommonResult.error().setCode(CommonConstant.AUTH_TOKEN_CHECK_RES_ERROR)
                    .setErrorCode(CommonConstant.AUTH_TOKEN_CHECK_RES_MESSAGE)
                    .setMessage("appToken验证失败!");
        }
        // 将当前的上下文填入到请求头中
        String currentContextStr = GsonUtils.serialize(currentContext);
        String encryptContext;
        try {
            encryptContext = AesUtils.encrypt(currentContextStr, bootConfigAppConfig.getSecretKey());
        } catch (Exception e) {
            log.error("UserAppInfoMssaHandler currentContext encrypt error {}", e.getMessage());
            return CommonResult.error().setCode(CommonConstant.AUTH_TOKEN_CONTEXT_ENCRYPT_ERROR)
                    .setErrorCode(CommonConstant.AUTH_TOKEN_CONTEXT_ENCRYPT_MESSAGE)
                    .setMessage("当前上下文加密异常!");
        }
        log.debug("UserAppInfoMssaHandler context header str is {}", encryptContext);
        ServerHttpRequest mutatedTraceRequest = exchange.getRequest().mutate().header(OPEN_SERVICE_CONTEXT, encryptContext).build();
        return exchange.mutate().request(mutatedTraceRequest).build();
    }
}
